package com.selvn.encryptnote;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

public class EncryptNoteXmlParser
{
	private static final String ns = null;

	public List<HashMap<String, String>> parse(InputStream in)
			throws XmlPullParserException, IOException
	{
		try
		{
			XmlPullParser parser = Xml.newPullParser();
			parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
			parser.setInput(in, null);
			parser.nextTag();
			return readFeed(parser);
		} finally
		{
			in.close();
		}
	}

	private List<HashMap<String, String>> readFeed(XmlPullParser parser)
			throws XmlPullParserException, IOException
	{
		List<HashMap<String, String>> items = new ArrayList<HashMap<String, String>>();

		parser.require(XmlPullParser.START_TAG, ns, "r");
		while (parser.next() != XmlPullParser.END_TAG)
		{
			if (parser.getEventType() != XmlPullParser.START_TAG)
			{
				continue;
			}
			String name = parser.getName();
			// Starts by looking for the lists tag
			if (name.equals("lists"))
			{
				while (parser.next() != XmlPullParser.END_TAG)
				{
					String name1 = parser.getName();
					// only handle the item tag
					if (name1.equals("item"))
					{
						items.add(readItem(parser));
					}
					else
					{
						skip(parser);
					}
				}
			}
			else
			{
				skip(parser);
			}
		}
		return items;
	}

	public static class Entry
	{
		public final String title;
		public final String link;
		public final String summary;

		private Entry(String title, String summary, String link)
		{
			this.title = title;
			this.summary = summary;
			this.link = link;
		}
	}

	// Parses the contents of an entry. If it encounters a title, summary, or
	// link tag, hands them off
	// to their respective "read" methods for processing. Otherwise, skips the
	// tag.
	private HashMap<String, String> readItem(XmlPullParser parser)
			throws XmlPullParserException, IOException
	{
		parser.require(XmlPullParser.START_TAG, ns, "item");
		String id = parser.getAttributeValue(null, "id");
		String title = null;
		String body = null;
		String createDate = null;
		String modifyDate = null;
		String location1 = null;
		String location2 = null;
		while (parser.next() != XmlPullParser.END_TAG)
		{
			if (parser.getEventType() != XmlPullParser.START_TAG)
			{
				continue;
			}
			String name = parser.getName();
			if (name.equals("title"))
			{
				parser.require(XmlPullParser.START_TAG, ns, "title");
				title = readText(parser);
				parser.require(XmlPullParser.END_TAG, ns, "title");
			} else if (name.equals("body"))
			{
				parser.require(XmlPullParser.START_TAG, ns, "body");
				body = readText(parser);
				parser.require(XmlPullParser.END_TAG, ns, "body");
			} else if (name.equals("createDate"))
			{
				parser.require(XmlPullParser.START_TAG, ns, "createDate");
				createDate = readText(parser);
				parser.require(XmlPullParser.END_TAG, ns, "createDate");
			} else if (name.equals("modifyDate"))
			{
				parser.require(XmlPullParser.START_TAG, ns, "modifyDate");
				modifyDate = readText(parser);
				parser.require(XmlPullParser.END_TAG, ns, "modifyDate");
			} else if (name.equals("location1"))
			{
				parser.require(XmlPullParser.START_TAG, ns, "location1");
				location1 = readText(parser);
				parser.require(XmlPullParser.END_TAG, ns, "location1");
			} else if (name.equals("location2"))
			{
				parser.require(XmlPullParser.START_TAG, ns, "location2");
				location2 = readText(parser);
				parser.require(XmlPullParser.END_TAG, ns, "location2");
			} else
			{
				skip(parser);
			}
		}
		HashMap<String, String> noteHashMap = new HashMap<String, String>();
		noteHashMap.put(Config.DBID, id);
		noteHashMap.put(Config.DBTITLE, title);
		noteHashMap.put(Config.DBBODY, body);
		noteHashMap.put(Config.DBCREATEDATE, createDate);
		noteHashMap.put(Config.DBMODIFY, modifyDate);
		noteHashMap.put(Config.DBLOCATION1, location1);
		noteHashMap.put(Config.DBLOCATION2, location2);
		return noteHashMap;
	}

	// For the tags title and summary, extracts their text values.
	private String readText(XmlPullParser parser) throws IOException,
			XmlPullParserException
	{
		String result = "";
		if (parser.next() == XmlPullParser.TEXT)
		{
			result = parser.getText();
			parser.nextTag();
		}
		return result;
	}

	private void skip(XmlPullParser parser) throws XmlPullParserException,
			IOException
	{
		if (parser.getEventType() != XmlPullParser.START_TAG)
		{
			throw new IllegalStateException();
		}
		int depth = 1;
		while (depth != 0)
		{
			switch (parser.next())
			{
			case XmlPullParser.END_TAG:
				depth--;
				break;
			case XmlPullParser.START_TAG:
				depth++;
				break;
			}
		}
	}
}
